#define header_len 4
inline int packOne(lua_State* L,int index,google::protobuf::Message* message,const google::protobuf::FieldDescriptor* fieldDescriptor,cosnt google::protobuf::Reflection* flection)
{
    const char* valuename = fieldDescriptor->name().c_str();
    int type = lua_getfield(L,index,valuename); 
    if(type == LUA_TNIL)
    {
        return luaL_error("find the field%s not find",valuename);   
    }
    google::protobuf::FieldDescriptor::CppType cpp = fieldDescriptor->cpp_type();
    swtich(cpp)
    {
        using namespace google::protobuf;
        case FieldDescriptor::CPPTYPE_INT32:
        {
            if(fieldDescriptor->is_repeated())
            {
                if(type == LUA_TTABLE)
                {
                    lua_pushnil(L);
                    while(lua_next(L,-2))
                    {
                        lua_Number value = lua_tonumber(L,-1);
                        lua_pop(L,1);
                        flection->AddUInt32(message,fieldDescriptor,static_cast<uint32>(value));
                    }
                }
            }
            else
            {
                lua_Number value = lua_tonumber(L,-1);
                flection->SetUint32(message,fieldDescriptor,static_cast<uint32>(value));
            }
        }
        break;
        case FieldDescriptor::CPPTYPE_MESSAGE:
        {
            if (type != LUA_TTABLE)
            {
                return luaL_error(L,"probuf is messagetype ,but% is not table",valuename);
            }
            
            google::protobuf::Message* message = flection->MutableMessage(message,fieldDescriptor);
            const google::protobuf::Descriptor* subDescriptor = fieldDescriptor->message_type();
            const subfieldcount = subDescritor->field_count();
            for(int index=0;index < subfieldcount;index++)
            {
                const google::protobuf::FieldDescriptor* subfieldDescritor = subDescritor->find(index);
                packOne(L,-1,submessage,subfieldDescriptor,subflection);
            }
        }
        break;
    }
    
    lua_pop(L,1);
    return 0;
}
inline void packTable(lua_State* L,int index,google::protobuf::Message* message,const google::protobuf::FieldDescritpor* fieldDescritor,const google::protobuf::Reflection* flection)
{
    size_t length = lua_rawlen(L,index);
    for(size_t index = 0;index < length;index++)
    {
        int type = lua_rawgeti(L,-1,index);
        if(type ~= LUA_TNIL)
        {
            packOne(L,-1,mesage,fieldDescriptor,flection);
        }
    }
}
inline int lencode(Lua_State* L)
{
    cosnt char* messagename = lua_tostring(L,1);
    char* pData = new char[1024];
    const google::protobuf::Descriptor* descriptor = google::protobuf::DescriptorPool::generated_pool()->FindMessageByType(std::string(messagename));
    google::protobuf::message* mseeage = NULL;
    unsigned int length = 0;
    length += sizeof(length);
    short namelength = std::string(messagename).length();
    *(short*)(pData+length) = namelength;
    length += sizeof(short);
    memcpy(pData+ length,messagename,namelength);
    length += namelength;
    
    const google::protobuf::Message* prototype = 
        google::protobuf::MessageFactory::generated_factory()->GetProtytype(descriptor);
        
    message = prototype->new();
    cosnt google::protobuf::Relfection* flection = message->GetReflection();
    int fieldCount = descriptor->field_count();
    for(int index=0;index < fieldCount;++index)
    {
            const google::protobuf::FieldDescriptor* fieldDescriptor = descriptor->field(index);
            if(fieldDescriptor)
            {
                packOne(L,2,message,fieldDescriptor,flection);
            }
    }
    std::string data;
    if(message->SerializeToString(&data))
    {
        memcpy(pData + length,data.c_str(),data.length());
        length += data.length();
    }
    *(unsigned int*) = length;
    lua_pushlstring(L,pData,length);
    delete(message);
    return 1;
}

inline int unpackOne(lua_State* L,int index,const google::protobuf::Message* message,const google::protobuf::FieldDescriptor* fieldDescriptor,const google::protobuf::Relfection* flection)
{
    const char* valuename = fieldDescriptor->name().c_str();
    google::protobuf::FieldDescriptor::CppType cpptype = fieldDescriptor->cpp_type();
    switch(cpptype)
    {
        using namespace google::protobuf;
        case FieldDescriptor::CPPTYPE_MESSAGE:
        {
            lua_newtable(L);
            google::prototbuf::Message* submessage = flection->MutableMessage(const_cast<Message*>(message),fieldDescriptor);
            Descriptor* subdescriptor = fieldDescriptor->message_type();
            Subflection* subflection = submessage->getRelection();
            int subfieldcount = subdescriptor->field_count();
            for(int index=0;index < subfieldcount;index++)
            {
                FieldDescriptor* subfielddescriptor = subDescriptor->field(index);
                unpackOne(L,-1,submessage,subfieldDescritpor,subflection);
            }
            lua_setfield(L,-2,valuename);
        }
        break;
        case UINT32:
        {
            if(fieldDescriptor->is_repeated())
            {
                lua_newtable(L);
                int number = fieldDescriptor->number();
                for(int index=0;index <= number;index++)
                {
                    uint32 value = flection->GetRepeatedUint32(*message,fieldDescriptor,index);
                    lua_pushnumber(L,value);
                    lua_rawseti(L,-1,index+1);
                }
            }
            else
            {
                uint32 value = flection->GetUint32(*message,fieldDescritor);
                lua_pushnumber(L,value);
            }
            lua_setfield(L,-2,valuename);
        }
        break;
    }
}
inline int ldecode(lua_State*L)
{
    size_t len = 0;
    
    using namespace google::protobuf;
    Descriptor* descriptor = DescriptorPool::generated_pool()->FindMessageTypeByName(messagename);
    Message* prototype = MessageFactory::generated_factory()->GetProtoType(descriptor);
    Mesage* message = prototype->New();
    if(message->ParseFromData(pData,length))
    {
       Reflection* flection = prototype->GetRelfection();
       int fieldCount = descriptor->field_count();
       lua_newtable(L);
       number = 1;
       for(int index=0;index<fieldCount;++index)
       {
                FieldDescriptor* fieldDescriptor = descriptor->field(index);
                if(fieldDescriptor)
                {
                    unpackOne(L,-1,message,fieldDescriptor,flection);
                }
       }
    }
    return number;
}